package com.king.juc.n8.threadpooldemo.timerdemo;

import lombok.extern.slf4j.Slf4j;

import java.util.Timer;
import java.util.TimerTask;
import java.util.concurrent.*;

/**
 * Timer 案例
 *
 * @author king
 * @date 2020/12/12 15:22
 */
@Slf4j(topic = "c.TimerTest")
public class TimerTest {
    public static void main(String[] args) {
        // 串行运行
        testTimer();

        // 解决Timer串行问题
        ScheduledExecutorService pool = Executors.newScheduledThreadPool(2);

        pool.schedule(() -> log.debug("task 1"), 1, TimeUnit.SECONDS);
        pool.schedule(() -> log.debug("task 2"), 1, TimeUnit.SECONDS);

        // 固定速率执行任务,如果任务耗时超过规定时间, 则下一轮任务在本轮任务结束后立即运行
        pool.scheduleAtFixedRate(() -> log.debug("running..."), 1, 1, TimeUnit.SECONDS);

        // 固定速率执行任务,如果任务耗时超过规定时间, 则下一轮任务在本轮任务结束后间隔设定时间后运行
        pool.scheduleWithFixedDelay(() -> log.debug("running..."), 1, 1, TimeUnit.SECONDS);
    }

    private static void errorDemo() throws ExecutionException, InterruptedException {
        ExecutorService pool = Executors.newFixedThreadPool(1);
        pool.submit(() -> {
            try {
                log.debug("run...");
                int i = 1 / 0;
            } catch (Exception e) {
                log.error("error", e);
            }
        });

        Future<Boolean> f = pool.submit(() -> {
            log.debug("run...");
            int i = 1 / 0;
            return true;
        });
        log.debug("result: ", f.get());
    }

    private static void testTimer() {
        Timer timer = new Timer();
        TimerTask task1 = new TimerTask() {
            @Override
            public void run() {
                log.debug("task 1");
                // 后续任务需等待休眠结束
//                sleep(2);

                // 后续任务因该异常导致终止退出
                int i = 1 / 0;
            }
        };
        TimerTask task2 = new TimerTask() {
            @Override
            public void run() {
                log.debug("task 2");
            }
        };

        log.debug("start...");
        timer.schedule(task1, 1000);
        timer.schedule(task2, 1000);
    }
}
